package com.company.cloud.mini.modules.sdk.api;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.company.cloud.mini.modules.sdk.response.AccessTokenEntity;
import com.company.cloud.sdk.core.config.WxApiConfig;
import com.company.cloud.sdk.core.constant.SdkReturnEnum;
import com.company.cloud.sdk.core.utils.StringUtils;
import com.company.cloud.mini.modules.sdk.response.DecryptModel;
import com.company.cloud.mini.modules.sdk.response.ThirdUserEntity;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Map;

public class MiniWxApi {

    /*小程序获取*/
    private static final String JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code";

    /*获取access_token*/
    private static final String GETTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}";

    /**
     * 获取access_token
     * @param config
     * @return
     */
    public static AccessTokenEntity getToken(WxApiConfig config){
        String url= getTokenUrl(config);
        if (StringUtils.isEmpty(url)) {
            return AccessTokenEntity.error(SdkReturnEnum.WX_Cofig_ERROR, new AccessTokenEntity());
        }
        String result = HttpUtil.get(url);
        if(StringUtils.isEmpty(result)) {
            return AccessTokenEntity.error(SdkReturnEnum.WX_OpenID_Read_Error, new AccessTokenEntity());
        }
        Map<String,String> resultMap= JSON.parseObject(result, Map.class);
        String accessToken=resultMap.get("access_token");
        if(StringUtils.isEmpty(accessToken)) {
            return AccessTokenEntity.error(SdkReturnEnum.WX_OpenID_Read_Error, new AccessTokenEntity());
        }
        return AccessTokenEntity.ok(new AccessTokenEntity(accessToken));
    }

    /**
     * 读取openid,session_key
     * @param code
     * @param config
     * @return
     */
    public static ThirdUserEntity getThirdUser(String code, WxApiConfig config) {
        String url= getJsCode2SessionURL(code,config);
        if (StringUtils.isEmpty(url)) {
            return ThirdUserEntity.error(SdkReturnEnum.WX_Cofig_ERROR, new ThirdUserEntity());
        }
        Map<String, Object> paramMap=new HashMap<String, Object>();
        String result= HttpUtil.post(url, paramMap);
        if(StringUtils.isEmpty(result)) {
            return ThirdUserEntity.error(SdkReturnEnum.WX_OpenID_Read_Error, new ThirdUserEntity());
        }
        Map<String,String> resultMap= JSON.parseObject(result, Map.class);
        String openId=resultMap.get("openid");
        String sessionKey= resultMap.get("session_key");
        if(StringUtils.isEmpty(openId) || StringUtils.isEmpty(sessionKey)) {
            return ThirdUserEntity.error(SdkReturnEnum.WX_OpenID_Read_Error, new ThirdUserEntity());
        }
        return ThirdUserEntity.ok(new ThirdUserEntity(openId,sessionKey));
    }

    /**读取JSCODE2SESSION_URL*/
    public static String getJsCode2SessionURL(String code, WxApiConfig config) {
        if(config!=null
                && !StringUtils.isEmpty(config.getWxAppID())
                && !StringUtils.isEmpty(config.getWxAppSecret())) {
            String url= StrUtil.format(JSCODE2SESSION_URL, config.getWxAppID(),config.getWxAppSecret(),code);
            return url;
        } else {
            return "";
        }
    }

    /**
     * 加密数据解密算法
     * @param encryptedData
     * @param iv
     * @param sessionKey
     * @return
     */
    public static DecryptModel decryptData(String encryptedData, String iv, String sessionKey) {
        try {
            if(StringUtils.isEmpty(encryptedData) || StringUtils.isEmpty(iv) || StringUtils.isEmpty(sessionKey)){
                DecryptModel.error(SdkReturnEnum.WX_Cofig_ERROR);
            }
            byte[] encrypData = Base64.decode(encryptedData);
            byte[] ivData = Base64.decode(iv);
            byte[] sessionKeyByte = Base64.decode(sessionKey);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(sessionKeyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            //解析解密后的字符串
            String phoneNum = new String(cipher.doFinal(encrypData),"UTF-8");
            JSONObject jsonObjects = JSONObject.parseObject(phoneNum);
            return DecryptModel.ok(new DecryptModel(jsonObjects.getString("phoneNumber")));
        }catch (Exception e){
            System.out.println(e);
            return DecryptModel.error(SdkReturnEnum.WX_Cofig_ERROR, new DecryptModel());
        }
    }

    /**读取JSCODE2SESSION_URL*/
    public static String getTokenUrl(WxApiConfig config) {
        if(config!=null
                && !StringUtils.isEmpty(config.getWxAppID())
                && !StringUtils.isEmpty(config.getWxAppSecret())) {
            String url= StrUtil.format(GETTOKEN_URL, config.getWxAppID(),config.getWxAppSecret());
            return url;
        } else {
            return "";
        }
    }

//    public static void main(String[] args) throws Exception{
//
////        String encryptedData = "qduuaQLUq02PZmwRkyHK3V72yE902Yq1UPhvsvK/GPkfdowcB+XXG0NEY4AmMv/TCbTYaJIHInjf2Hc2IOCj0GNVVUgW7TGGcTY2F0I5r3GaYoMGODPwMbTiUULUd6dyTNDpRuXvW2xICfzqcmXAdDnXaGNNKMG1lGf0BY730MB0frgQ5R9DiQW4iKhlgABbhPWoFTpUYckCbJhGvm7jLQ==";
////        String iv = "R+c1y8HADVh7Kr/jB7W3jA==";
////        String sessionKey = "Jb2QB4W/SYm9DNA89EIZxw==";
////        DecryptModel model = decryptData(encryptedData,iv,sessionKey);
////        System.out.println(model.getReturnCode());
////        System.out.println(model.getReturnMsg());
////        System.out.println(model.getDecryptStr());
//
//        WxApiConfig config = new WxApiConfig();
//        config.setWxAppID("wxe5bb3017fd108c5d");
//        config.setWxAppSecret("c1d31167a5edc9c66772bea7009ee160");
//        AccessTokenEntity entity = getToken(config);
//        System.out.println(JSONObject.toJSONString(entity));
//    }

}
